package com.apes.fn.misc.contract;

import com.apes.fn.business.fixedLoss.modle.LossQuotation;
import com.apes.fn.business.fixedLoss.repository.LossQuotationRepository;
import com.apes.fn.server.servicePlan.model.ServicePlan;
import com.apes.fn.server.servicePlan.repository.ServicePlanRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.ApesBean;
import com.apes.framework.jpa.BaseModel;
import com.apes.framework.jpa.logger.ApesRelation;
import com.apes.framework.jpa.logger.ApesRelationRepository;
import com.apes.framework.jpa.repository.CustomRepository;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.soe.metadata.BusinessType;
import com.apes.framework.plugin.soe.store.database.repository.BusinessTypeRepository;
import com.apes.framework.query.SqlService;
import com.apes.framework.util.DateUtil;
import com.apes.framework.util.JpaUtil;
import com.apes.framework.util.MapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by lishikun on 2021/8/30 11:07
 */
@Service("documentNetworkService")
public class DocumentNetworkService extends DomainService {

    @Autowired
    ApesRelationRepository apesRelationRepository;

    @Autowired
    EntityManager entityManager;
    /**
     * 通过条件获取关系网
     * @param request
     * @return
     */
    public List getDocumentNetworkByFilters(SimpleRequest request) {
        List<Map> filters = request.get("condition");
        Map fieldMap = new HashMap();
        List  response = new ArrayList();
        for (Map filter : filters) {
            fieldMap.put(filter.get("field"), filter.get("value"));
        }
        List<ApesRelation> apesRelationList = getApesRelationList(fieldMap, filters);
        for (ApesRelation apesRelation : apesRelationList) {
            BusinessType businessType = SpringManager.getBean(BusinessTypeRepository.class).findFirstById(apesRelation.getBusinessType());
            List title = new ArrayList();
            if (apesRelation.getBusinessCreateDate() != null)
                title.add(DateUtil.format(apesRelation.getBusinessCreateDate(), "yyyy-MM-dd HH:mm:ss"));
            title.add(apesRelation.getBusinessKey());
            title.add(businessType != null ? businessType.getName() : "");
            response.add(MapUtil.mapper("title", title ,
                    "condition", nextLevelFilters(filters, apesRelation)));
        }
        return response;
    }

    /**
     * 下一层条件
     * @param filters
     * @return
     */
    private List<Map> nextLevelFilters(List<Map> filters,  ApesRelation apesRelation) {
        List<Map> newList = new ArrayList<>();
        for (Map filter : filters) {
            newList.add(MapUtil.mapped(filter));
        }
        boolean init = false;
        for (Map filter : newList) {
            if (filter.get("field").equals("businessType")) {
                filter.put("value", apesRelation.getBusinessType());
                init = true;
            }
            if (filter.get("field").equals("ID")) filter.put("value", apesRelation.getBusinessKey());
        }
        if (!init) {
            newList.add(MapUtil.mapper("field", "businessType", "value", apesRelation.getBusinessType()));
            newList.add(MapUtil.mapper("field", "ID", "value", apesRelation.getBusinessKey()));
        }
        return newList;
    }

    /**
     * 获取关系网第一层数据
     * @param fieldMap
     * @return
     */
    private List<ApesRelation> getApesRelationList(Map fieldMap, List filters) {
        String voucher = Boolean.valueOf(fieldMap.get("Voucher").toString()) == true ? null : "Voucher";
        String invoice = Boolean.valueOf(fieldMap.get("Invoice").toString()) == true ? null : "Invoice";

        if (fieldMap.get("TYPE").equals("10") && fieldMap.get("businessType") == null) {
            return getApesRelationByCar(fieldMap, filters);
        } else if( fieldMap.get("TYPE").equals("0") && fieldMap.get("businessType") == null) {
            if (fieldMap.get("ID") == null) throw new RuntimeException("单号不允许为空");
            return findAllByBusinessKeyLevelOne(fieldMap.get("ID").toString(), voucher, invoice);
        } else {
            return findAllByBusinessKeyAndBusinessType(fieldMap.get("ID").toString(), fieldMap.get("businessType").toString(), voucher, invoice);
        }
    }

    /**
     * TODO通过车牌号获取关系网数据
     * @param fieldMap
     * @return
     */
    private List<ApesRelation> getApesRelationByCar(Map fieldMap, List filters) {
        String carLicense = fieldMap.get("CAR_LICENSE") != null ? fieldMap.get("CAR_LICENSE").toString() : null;
        if (carLicense == null) throw new RuntimeException("车牌不允许为空");
        List businessKeys = getBusinessKeysByField(fieldMap, filters);
        List<ApesRelation> allByBusinessKeysLevelOne = new ArrayList<>();
        if(businessKeys.size() == 0) return allByBusinessKeysLevelOne;
        allByBusinessKeysLevelOne = apesRelationRepository.findAllByBusinessKeysLevelOne(businessKeys);
        return allByBusinessKeysLevelOne;
    }

    /**
     * 通过条件获取单据号
     * @param fieldMap
     * @return
     */
    private List getBusinessKeysByField(Map fieldMap,List filters) {
        String deptId = fieldMap.get("DEPT_ID")!= null ? fieldMap.get("DEPT_ID").toString() : null ;
        String carLicense = fieldMap.get("CAR_LICENSE") != null ? fieldMap.get("CAR_LICENSE").toString() : null;
        List<ServicePlan> servicePlans;
        List<LossQuotation> lossQuotations;
        if (deptId == null) {
            JpaDsl.toCriteria(filters);
            servicePlans = SpringManager.getBean(ServicePlanRepository.class).findAll(JpaDsl.toCriteriaByEq("fnCustomerExpand.carLicense", carLicense));
            lossQuotations = SpringManager.getBean(LossQuotationRepository.class).findAll(JpaDsl.toCriteriaByEq("customerExpand.carLicense", carLicense));
        } else {
            servicePlans = SpringManager.getBean(ServicePlanRepository.class).findAll(JpaDsl.toCriteriaByEq("fnCustomerExpand.carLicense", carLicense, "belongDept.id", deptId));
            lossQuotations = SpringManager.getBean(LossQuotationRepository.class).findAll(JpaDsl.toCriteriaByEq("customerExpand.carLicense", carLicense,"fixedLossDept.id", deptId));
        }
        List<Object> servicePlanBusinessKeys = servicePlans.stream().map(servicePlan -> {
            return servicePlan.getId();
        }).collect(Collectors.toList());
        List lossQuotationBusinessKeys = lossQuotations.stream().map(lossQuotation -> {
            return lossQuotation.getId();
        }).collect(Collectors.toList());
        servicePlanBusinessKeys.addAll(lossQuotationBusinessKeys);
        return servicePlanBusinessKeys;
    }

    /**
     * 根据类型获取第一层数据
     * @param businessType
     * @param voucher
     * @param invoice
     * @return
     */
    public List<ApesRelation> findAllByBusinessKeyLevelOne(String businessType, String voucher, String invoice) {
        if (voucher == null ) voucher = "and 1 = 1" ;else voucher = " AND T.BUSINESS_TYPE != 'Voucher' ";
        if (invoice == null ) invoice = "and 1 = 1"; else invoice = " AND T.BUSINESS_TYPE != 'Invoice' ";
        String s[] = new String[] {businessType, voucher, invoice};
        String format = String.format("SELECT T.*, LEVEL " +
                "                   FROM IR_RELATION T WHERE LEVEL = 1  " + voucher + invoice  +
                "                   START WITH T.BUSINESS_KEY =  '" + businessType  + "'" +
                "                   CONNECT BY PRIOR T.BUSINESS_KEY = T.SOURCE_BUSINESS_KEY", s);
        Query query = entityManager.createNativeQuery( format, ApesRelation.class);
        List resultList = query.getResultList();
        return resultList;
    }

    /**
     * 根据类型和单号获取下一层数据
     * @param businessKey
     * @param businessType
     * @param voucher
     * @param invoice
     * @return
     */
    public List<ApesRelation> findAllByBusinessKeyAndBusinessType(String businessKey, String businessType,  String voucher, String invoice) {
        if (voucher == null ) voucher = "and 1 = 1" ;else voucher = " AND T.BUSINESS_TYPE != 'Voucher' ";
        if (invoice == null ) invoice = "and 1 = 1"; else invoice = " AND T.BUSINESS_TYPE != 'Invoice' ";
        String s[] = new String[] {businessType, voucher, invoice};
        String format = String.format("SELECT T.*, LEVEL " +
                "   FROM IR_RELATION T WHERE LEVEL = 2 %s %s" +
                "   START WITH T.BUSINESS_KEY = '%s' AND T.BUSINESS_TYPE = '%s'" +
                "   CONNECT BY PRIOR T.BUSINESS_KEY = T.SOURCE_BUSINESS_KEY", voucher, invoice, businessKey, businessType);
        Query query = entityManager.createNativeQuery( format, ApesRelation.class);
        List resultList = query.getResultList();
        return resultList;
    }
}
